# -*- coding: utf-8 -*-

import datetime
import time
import re
from osv import fields, osv
from mailnotifier import MailNotifier
from locale import str

class incidencia(osv.osv):
    _name = 'incidencia'
    _email_user = "gabriel@socetel.es"
    _email_pass = "61497250"
    
    '''Funciones'''
    
    def get_user(self,cr,uid,ids):
        return uid
    
    def get_seq(self,cr,uid,context=None):
        inc_tree = self.search(cr,uid,[])
        incidencias = self.browse(cr,uid,inc_tree)
        org = self.get_curr_user_org(cr, uid)
        max = org*100000
        for inc in incidencias:
            readid = ""+inc.identifier
            idnum = int(readid.split("C")[1])
            if idnum<((org+1)*100000): # Si pertenece al mismo rango de organizacion 
                if idnum>max:
                    max = idnum
        max+=1
        idstr = "INC"+"{0:05d}".format(max)
        return idstr
    
    def get_user_type(self,cr,uid,ids):
        res = None
        users = self.pool.get('res.users')
        curr_user = users.browse(cr, uid, uid)
        for group in curr_user.groups_id:
            if group.name == "Responsable":
                res = "Responsable"
            if group.name == "Usuario":
                res = "Usuario"
            if group.name == "Gestor":
                res = "Gestor"
            if group.name == "Administrador":
                res = "Administrador"
        return res
    
    def check_text(self,in_text):
        if in_text:
            s = "" + in_text
            s = s.strip()
            if len(s) < 3:
                return False
            else:
                return True   
        return in_text
    
    def get_curr_user_org(self,cr,uid,ids=None):
        users = self.pool.get('res.users')
        curr_user = users.browse(cr, uid, uid)
        return curr_user.organization_id.id 
       
    def get_curr_user_resp(self,cr,uid,ids,context=None):
        res = None
        curr_user_org_id = self.get_curr_user_org(cr, uid, ids)
        if curr_user_org_id:
            org_rec = self.pool.get('organizacion').browse(cr,uid,curr_user_org_id)
            if org_rec:
                res = org_rec.responsible_id.id
        return res
    
    def _get_inst_org_ids(self,cr,uid,ids,context=None): #Devuelve lista
        arr = []
        users = self.pool.get('res.users')
        curr_user = users.browse(cr, uid, uid, context)
        curr_user_org = curr_user.organization_id.id
        insts_tree = self.pool.get('instalacion').search(cr, uid, [])
        insts = self.pool.get('instalacion').browse(cr, uid, insts_tree, context)
        for inst in insts:
            if curr_user_org == inst.organization_id.id:
                arr.append(inst.id)
        return arr
    
    def get_inst_org_ids(self, cr, uid, ids, field_name, arg, context=None):  #Devuelve dict
        res = {}
        res[ids[0]] = self._get_inst_org_ids(cr, uid, ids, context)
        return res
    
    def get_tipo_org_ids(self, cr, uid, ids, field_name, arg, context=None): # DICT
        res = {}
        res[ids[0]] = self._get_tipo_org_ids(cr, uid, ids, context)
        return res
    
    def _get_tipo_org_ids(self, cr, uid, ids, context=None): #LIST
        arr = []
        users = self.pool.get('res.users')
        curr_user = users.browse(cr, uid, uid, context)
        curr_user_org = curr_user.organization_id.id
        tipos_tree = self.pool.get('tipo').search(cr, uid, [])
        tipos = self.pool.get('tipo').browse(cr, uid, tipos_tree, context)
        for tipo in tipos:
            if curr_user_org == tipo.organization_id.id:
                arr.append(tipo.id)
        return arr
    
    def get_org_uids(self, cr, uid, ids, field_name, arg, context=None): #DICT
        res = {}
        res[ids[0]] = self._get_org_uids(cr, uid, ids, context)
        return res
    
    def _get_org_uids(self, cr, uid, ids, context=None): #LISTA
        arr=[]
        users = self.pool.get('res.users')
        curr_user = users.browse(cr, uid, uid, context)
        curr_user_org = curr_user.organization_id.id
        users_tree = users.search(cr,uid,[])
        all_users = users.browse(cr,uid,users_tree,context)
        for user in all_users:
            if curr_user_org == user.organization_id.id:
                arr.append(user.id)
        return arr

    
    def _calc_dias(self, cr, uid, ids, field_name, arg, context=None):
        res = {}
        incidencias = self.browse(cr, uid, ids)
        for incidencia in incidencias:
            if not incidencia.close_date:
                fc  = time.localtime()
                fcierre = datetime.datetime(*fc[:3])
            else:
                fc = time.strptime(incidencia.close_date, '%Y-%m-%d %H:%M:%S')
                fcierre = datetime.datetime(*fc[:3])
            fa = time.strptime(incidencia.open_date, '%Y-%m-%d %H:%M:%S')                
            fapertura = datetime.datetime(*fa[:3])
            dif =  fcierre - fapertura
            res[incidencia.id] = dif.days
        return res
    


    _columns = {
                'identifier': fields.char('ID', size=32, readonly=True),
                'name': fields.char('Nombre', size=128, required=True),
                'open_date': fields.datetime('Fecha de apertura', readonly='True'),
                'validate_date': fields.datetime('Fecha de validación', readonly='True'),
                'process_date': fields.datetime('Fecha de tramitación', readonly='True'),
                'close_date': fields.datetime('Fecha de cierre', readonly='True'),
                'description': fields.text('Descripción',  required='True'),
                'observations': fields.text('Observaciones'),
                'state': fields.selection([('0', 'Nueva'),('1','Validada') , ('2', 'Tramitada'), ('3', 'Finalizada'), ('4', 'Cancelada')],'Estado'),  # Estado
                'clientuser_id': fields.many2one('res.users', 'Usuario', help='Usuario', select=True, required="True" ),  # clientuser 
                'responsible_id': fields.many2one('res.users', 'Responsable', help='Responsable'),  # Resp 
                'manager_id': fields.many2one('res.users', 'Gestor', help='Responsable'),  # Resp 
                'urgency': fields.selection([('high','Alta'),('medium','Media'),('low','Baja')],'Urgencia',required="True"),
                'file': fields.binary('Fichero'),
                'file_name': fields.char('FID',size=128),
                'file_res': fields.binary('Fichero Resolución'),
                'file_res_name': fields.char('FRID',size=128),
               
                'duration_days':fields.function(_calc_dias, method=True,type='integer',string='Días', store=False),
                'organization_id': fields.many2one('organizacion', 'Organización'),
                'type_id': fields.many2one('tipo', 'Tipo',required=True),
                 
                'instalacion_id': fields.many2one('instalacion', 'Instalación', required=True),           
                
                'inst_org_ids':fields.function(get_inst_org_ids, method=True, type='many2many', store=False, fnct_search=None),      
                'user_org_ids':fields.function(get_org_uids, method=True, type='many2many', store=False, fnct_search=None),
                'tipo_org_ids':fields.function(get_tipo_org_ids, method=True, type='many2many', store=False, fnct_search=None),
                
                #'inst_org_ids': fields.function(_get_inst_org_ids, type='char', string='ids',store=False),
                'create_uid': fields.many2one('res.users', 'Creado por', select=True, readonly=True),  # Registro
                'create_date': fields.datetime("Fecha de creación", select=True, readonly=True),
                'write_uid': fields.many2one('res.users', 'Modificado por', select=True, readonly=True),
                'write_date': fields.datetime("Fecha de modificación", select=True, readonly=True),

                }
    _defaults = {
                'open_date': fields.datetime.now,
                'organization_id': get_curr_user_org,
                'responsible_id': get_curr_user_resp,
                'inst_org_ids': _get_inst_org_ids,
                'tipo_org_ids': _get_tipo_org_ids,
                'user_org_ids': _get_org_uids,
                'clientuser_id': get_user,
                'state': '0',
                'urgency': 'low',
                'identifier': lambda self,cr,uid,context={}: self.get_seq(cr,uid,context),
    }
    
    _order = "open_date desc"
  
    def create(self, cr, uid, vals, context=None):
        if not vals.has_key('clientuser_id'): #Si no se especifica usuario se establece como usuario a si mismo
            vals.update({'clientuser_id': uid})
        if not vals.has_key('organization_id'): # Si no se especifica la organizacion se guarda la organizacion a la que pertenece el usuario especificado como usuario de la incidencia
            user = self.pool.get('res.users').browse(cr,uid,vals['clientuser_id'],context)    
            orgs = user.organization_id
            vals.update({'organization_id':orgs.id})       
        vals.update({'close_date':None}) # Los nuevos registros con fecha de cierre vacia
        if not self.check_text(vals['description']):
            raise osv.except_osv('No permitido', u'Descripción de la incidencia no válida')
        
        return super(incidencia,self).create(cr, uid, vals, context)

    def write(self, cr, uid, ids, vals, context=None):
        user_type = self.get_user_type(cr, uid, ids)
        curr_rec = self.browse(cr,uid,ids[0])
        state = curr_rec.state
        if user_type == "Usuario" or user_type == "Responsable":
            if  not self.check_text(curr_rec.description):
                raise osv.except_osv('No permitido', u'Descripción de la incidencia no válida')
            if  state != '0':
                raise osv.except_osv('No permitido', u'No se puede modificar una incidencia una vez validada o cancelada')         
                return None
        if user_type == "Gestor":
            if  not self.check_text(curr_rec.description):
                raise osv.except_osv('No permitido', u'Las Observaciones de la incidencia no son válidas')
            if state != '1' and state != '2':
                raise osv.except_osv('No permitido', u'No se puede modificar una incidencia finalizada o cancelada')         
                return None  
        return super(incidencia,self).write(cr, uid, ids, vals, context=None)


    def copy(self, cr, uid, ide, default=None, context=None):
        default['identifier'] = self.get_seq(cr, uid, context)
        default['open_date'] = time.strftime("%d-%m-%Y %H:%M:%S",time.gmtime())
        default['validate_date'] = default['process_date'] = default['close_date'] = default['observations'] = default['manager_id'] = None
        return super(incidencia,self).copy(cr, uid, ide, default, context=None)
    
    def validate(self, cr, uid, ids, context=None):
        vals = {}
        vals['state'] = '1'
        vals['validate_date'] = time.strftime("%d-%m-%Y %H:%M:%S",time.gmtime())
        self.write(cr, uid, ids, vals) 
        return True 
    
    def process(self, cr, uid, ids, context=None):
        vals = {}
        vals['state'] = '2'
        vals['process_date'] = time.strftime("%d-%m-%Y %H:%M:%S",time.gmtime()) 
        vals['manager_id'] = uid
        self.write(cr, uid, ids, vals)
        return True
    
    def end(self, cr, uid, ids, context=None):
        #Comprobar observaciones para generar avisos
        curr_rec = self.browse(cr,uid,ids,context)[0]
        resp_email =  curr_rec.responsible_id.email
        vals = {}
        if self.check_text(curr_rec.observations): 
            vals['state'] = '3'
            vals['close_date'] =time.strftime("%d-%m-%Y %H:%M:%S",time.gmtime())        
            self.write(cr, uid, ids, vals)
            curr_rec = self.browse(cr,uid,ids,context)[0]
            try:
            #a = fields.datetime.context_timestamp(cr,uid,datetime.datetime.strptime(curr_rec.open_date,"%Y-%m-%d %H:%M:%S"))
            #print a
            #print type(a)
                self.sendmail(cr,uid,curr_rec,resp_email)
            except:
                print "Error en el envio del email"      
        else:
            raise osv.except_osv('No permitido', u'Es necesario introducir observaciones para poder cerrar la incidencia.\nHaga clic en EDITAR y edite las observaciones en la pestaña RESOLUCIÓN')         
        return True
    
    def cancel(self, cr, uid, ids, context=None):
        #Comprobar observaciones para generar avisos si no es nuevo cancelado por el propio usuario     
        curr_rec = self.browse(cr,uid,ids,context)[0]
        resp_email =  curr_rec.responsible_id.email
        user_inc_email = curr_rec.clientuser_id.email
        vals = {}
        vals['manager_id'] = uid
        is_0 = curr_rec.state == '0'
        vals['state'] = '4'
        vals['close_date'] = time.strftime("%d-%m-%Y %H:%M:%S",time.gmtime())
        self.write(cr, uid, ids,vals)
        curr_rec = self.browse(cr,uid,ids,context)[0]    
        user_type = self.get_user_type(cr, uid, ids)      
        if not is_0:
            if self.check_text(curr_rec.observations):
                if user_type == "Gestor":
                    if resp_email: # Si el gestor tiene definido una direccion email
                        try:
                            self.sendmail(cr,uid,curr_rec,resp_email)
                        except:
                            print "Error en el envio del email"         
                if user_inc_email: # Si el usuario de la incidencia tiene definido una direccion email
                    try:
                        self.sendmail(cr,uid,curr_rec,user_inc_email)
                    except:
                        print "Error en el envio del email"
            else:
                raise osv.except_osv('No permitido', u'Debes introducir observaciones para cancelar la incidencia.\nHaga clic en EDITAR y edite las observaciones en la pestaña RESOLUCIÓN')             
        return True
        
    def applytz(self,cr,uid,strfmtdate,sfmt,fmt): #Aplica cambio de hora
        dto = datetime.datetime.strptime(strfmtdate,sfmt) #Obtiene datetime del registro
        dto_wo = fields.datetime.context_timestamp(cr,uid,dto) #Aplica time_zone del usuario
        str_dto_off = dto_wo.strftime(fmt) #Parsea al formato deseado
        return unicode(str_dto_off)   
    
    def printrec(self,curr_rec,opendate,valdate,procdate,closedate,estado):
        print curr_rec.name
        print type(curr_rec.name)
        print curr_rec.manager_id.name 
        print type(curr_rec.manager_id.name)
        print curr_rec.identifier 
        print type( curr_rec.identifier)
        print curr_rec.clientuser_id.name 
        print type(curr_rec.clientuser_id.name)
        print curr_rec.organization_id.name 
        print type(curr_rec.organization_id.name)
        print curr_rec.responsible_id.name 
        print type(curr_rec.responsible_id.name)
        print curr_rec.type_id.name 
        print type(curr_rec.type_id.name)
        print curr_rec.instalacion_id.name 
        print type(curr_rec.instalacion_id.name)
        print curr_rec.description 
        print type(curr_rec.description)
        print opendate 
        print type(opendate)
        print valdate 
        print type(valdate)
        print procdate 
        print type(procdate)
        print closedate 
        print type(closedate)
        print estado 
        print type(estado)
    
    def sendmail(self,cr,uid,curr_rec,dest,context = None):   
        sfmt = u"%Y-%m-%d %H:%M:%S"
        fmt = u"%d/%m/%Y %H:%M:%S"
        
        opendate = self.applytz(cr,uid,curr_rec.open_date,sfmt,fmt)
        valdate = self.applytz(cr,uid,curr_rec.validate_date, sfmt, fmt)
        if(curr_rec.process_date):
            procdate = self.applytz(cr,uid,curr_rec.process_date, sfmt, fmt)
        else:
            procdate = ""
        closedate = self.applytz(cr,uid,time.strftime(fmt,time.gmtime()), fmt, fmt)
        estado = ""
        if curr_rec.state == '4': 
            estado=u"Cancelada"
        if curr_rec.state == '3': 
            estado=u"Finalizada"
        subject = u"Incidencia " + curr_rec.identifier + ": " + estado
        #self.printrec(curr_rec, opendate, valdate, procdate, closedate,estado)
        text = u"<table cellpadding='7' cellspacing='7' border='1'>\
                <tr>\
                    <td colspan='2' bgcolor='CCCCFF'><b>Datos de alta</b></td>\
                    <td colspan='2'  bgcolor='CCCCFF'><b>Resoluci&oacute;n</b></td>\
                </tr>\
                <tr>\
                    <td>Nombre</td>\
                    <td><i>"+curr_rec.name+"</i></td>\
                    <td>Gestor</td>\
                    <td><i>"+curr_rec.manager_id.name+"</i></td>\
                </tr>\
                <tr>\
                    <td>ID</td>\
                    <td><i>"+curr_rec.identifier+"</i></td>\
                    <td>Fecha de tramitaci&oacute;n</td>\
                    <td><i>"+procdate+"</i></td>\
                </tr>\
                <tr>\
                    <td>Usuario de la incidencia</td>\
                    <td><i>"+curr_rec.clientuser_id.name+"</i></td>\
                    <td>Fecha de cierre</td>\
                    <td><i>"+closedate+"</i></td>\
                </tr>\
                <tr>\
                    <td>Organizacion</td>\
                    <td><i>"+curr_rec.organization_id.name+"</i></td>\
                    <td>Observaciones</td>\
                    <td><i>"+curr_rec.observations+"</i></td>\
                </tr>\
                <tr>\
                    <td>Fecha de alta</td>\
                    <td><i>"+opendate+"</i></td>\
                    <td></td>\
                    <td></td>\
                </tr>\
                <tr>\
                    <td>Fecha de validaci&oacute;n</td>\
                    <td><i>"+valdate+"</i></td>\
                    <td></td>\
                    <td></td>\
                </tr>\
                <tr>\
                    <td>Responsable</td>\
                    <td><i>"+curr_rec.responsible_id.name+"</i></td>\
                    <td></td>\
                    <td></td>\
                </tr>\
                <tr>\
                    <td>Tipo</td>\
                    <td><i>"+curr_rec.type_id.name+"</i></td>\
                    <td></td>\
                    <td></td>\
                </tr>\
                <tr>\
                    <td>Instalaci&oacute;n</td>\
                    <td><i>"+curr_rec.instalacion_id.name+"</i></td>\
                    <td></td>\
                    <td></td>\
                </tr>\
                <tr>\
                    <td>Descripci&oacute;n</td>\
                    <td><i>"+curr_rec.description+"</i></td>\
                    <td></td>\
                    <td></td>\
                </tr>\
            </table>"
        user = self._email_user
        password = self._email_pass
        print user
        print password
        sender = MailNotifier(user,password,'smtp.gmail.com')
        sender.sendmail(user, dest, subject, text, "html")
   
incidencia()
